<template>
  <div>
    <!-- 悬浮按钮 -->
    <div
      class="chat-float-button"
      ref="dragButton"
      :style="{ top: position.top + 'px', left: position.left + 'px' }"
      @mousedown="startDrag"
    >
      💬
    </div>

    <!-- 聊天窗口 -->
    <transition name="slide">
      <div v-if="isChatVisible" class="chat-box">
        <!-- 聊天窗口头部 -->
        <div class="chat-header">
          <span>{{ currentChatName || '选择或创建聊天' }}</span>
          <a-button type="text" icon="close" @click="isChatVisible = false" />
        </div>

        <div class="chat-body">
          <a-button
            type="text"
            @click="toggleChatList"
            style="position: absolute; left: -25px; top: 50%; transform: translateY(-50%)"
          >
            <a-icon v-if="isChatListVisible" type="caret-left" />
            <a-icon v-else type="caret-right" />
          </a-button>
          <!-- 左侧聊天列表 -->
          <div class="chat-list" v-show="isChatListVisible">
            <a-button type="primary" block @click="createNewChat">+ 新建聊天</a-button>
            <a-list :dataSource="chatList" bordered class="chat-list-items" size="small">
              <a-list-item
                v-for="chat in chatList"
                :key="chat.chatId"
                class="chat-item"
                :class="{ 'selected-chat': chat.chatId === currentChatId }"
              >
                <span @click="selectChat(chat)" class="chat-name">{{ chat.chatName }}</span>
                <a-button type="text" danger size="small" icon="delete" @click="confirmDeleteChat(chat.chatId)" />
              </a-list-item>
            </a-list>
          </div>

          <!-- 右侧聊天内容 -->
          <div class="chat-content" ref="chatContent">
            <div v-if="currentChatId" style="display: flex; flex-direction: column">
              <div
                v-for="msg in chatMessages"
                :key="msg.id"
                :class="['chat-message', msg.messageType === 'USER' ? 'chat-message-user' : 'chat-message-ai']"
              >
                <MarkdownRenderer v-if="msg.messageType != 'USER'" :markdown="msg.textContent"></MarkdownRenderer>
                <span v-else>{{ msg.textContent }}</span>
              </div>
              <!-- 还没有开始回答的时候 -->
              <div
                style="margin-top: 10px"
                v-if="isAnswering[currentChatId] && !flexChat[currentChatId]"
                :class="['chat-message', 'chat-message-ai']"
              >
                <a-spin tip="AI思考中..."> </a-spin>
              </div>
              <!-- 已经开始回答 -->
              <div v-if="flexChat[currentChatId]" :class="['chat-message', 'chat-message-ai']">
                <MarkdownRenderer :markdown="flexChat[currentChatId]"></MarkdownRenderer>
                <div style="margin-top: 10px">
                  <a-spin tip="AI思考中..."> </a-spin>
                </div>
              </div>
            </div>
            <div v-else class="empty-chat">请选择或新建聊天</div>
          </div>
        </div>

        <!-- 底部输入框 -->
        <div class="chat-footer">
          <a-input v-model="userInput" placeholder="输入消息..." @pressEnter="sendMessage" />
          <a-button type="primary" @click="sendMessage" :disabled="!currentChatId || isAnswering[currentChatId]"
            >发送</a-button
          >
          <a-tooltip placement="topLeft" title="停止思考" v-if="isAnswering[currentChatId]">
            <a-button @click="stopChat"><a-icon type="stop" theme="twoTone" /></a-button>
          </a-tooltip>
        </div>
      </div>
    </transition>
  </div>
</template>

<script>
import { getAction, postAction, deleteAction } from '@/api/manage'
import MarkdownRenderer from '../MarkdownRenderer.vue'
import { ACCESS_TOKEN } from '@/store/mutation-types'
import Vue from 'vue'
export default {
  data() {
    return {
      isChatVisible: false,
      position: { top: 550, left: 20 }, // 初始位置
      dragging: false,
      startX: 0,
      startY: 0,
      offset: { x: 0, y: 0 },
      aiThink: undefined,
      chatList: [], // 聊天窗口列表
      chatMessages: [], // 当前聊天记录
      currentChatId: null, // 当前选中的聊天窗口 ID
      currentChatName: '', // 当前聊天名称
      userInput: '', // 用户输入
      currentUserId: 1, // 当前用户 ID（可根据实际情况获取）
      eventSource: [],
      flexChat: {},
      isAnswering: [],
      answeringTimer: {},
      isChatListVisible: true,
      // isPageClosing: false,
    }
  },

  beforeDestroy() {
    // 在组件销毁前移除 beforeunload 事件监听器，避免内存泄漏
    window.removeEventListener('beforeunload', this.handleBeforeUnload)
    window.removeEventListener('unload', this.handleUnload)
  },
  components: {
    MarkdownRenderer,
  },
  mounted() {
    this.fetchChatList()
    window.addEventListener('beforeunload', this.handleBeforeUnload)
    window.addEventListener('unload', this.handleUnload)
  },
  methods: {
    handleUnload() {
      // 如果 unload 触发，说明用户真的离开了
      // this.isPageClosing = false
      console.log('用户刷新或关闭了页面')
      this.closeAllChat()
    },
    handleBeforeUnload(event) {
      event.preventDefault()
      event.returnValue = ''
      // this.isPageClosing = true
      // setTimeout(() => { 
      //   if (this.isPageClosing) {
      //     this.isPageClosing = false
      //     console.log('用户点击了取消')
      //     // console.log("用户真的离开，执行 cleanUpBeforeUnload");
      //   }
      // }, 0)
    },
    closeAllChat() {
      console.log('beforeunload')
      Object.values(this.eventSource).forEach((source) => source.close())
      const keys = Object.keys(this.isAnswering)
      keys.forEach((key) => {
        const url = `http://localhost:8080/ai/stop?chatId=${key}&token=${Vue.ls.get(ACCESS_TOKEN)}`
        navigator.sendBeacon(url) // 可靠地发送请求
      })
    },
    stopChat() {
      getAction('/ai/stop', { chatId: this.currentChatId }).then((res) => {})
    },
    toggleChatList() {
      this.isChatListVisible = !this.isChatListVisible
    },
    startDrag(event) {
      this.startX = event.clientX
      this.startY = event.clientY
      this.dragging = true
      this.offset.x = event.clientX - this.position.left
      this.offset.y = event.clientY - this.position.top
      document.addEventListener('mousemove', this.onDrag)
      document.addEventListener('mouseup', this.stopDrag)
    },
    onDrag(event) {
      if (!this.dragging) return
      let newX = event.clientX - this.offset.x
      let newY = event.clientY - this.offset.y
      const maxX = window.innerWidth - 50 // 限制拖拽范围
      const maxY = window.innerHeight - 50
      this.position.left = Math.max(0, Math.min(newX, maxX))
      this.position.top = Math.max(0, Math.min(newY, maxY))
    },
    stopDrag(event) {
      document.removeEventListener('mousemove', this.onDrag)
      document.removeEventListener('mouseup', this.stopDrag)

      // 计算鼠标移动的距离
      const deltaX = Math.abs(event.clientX - this.startX)
      const deltaY = Math.abs(event.clientY - this.startY)

      // 只有当鼠标基本没移动时，才打开聊天窗口
      if (deltaX < 5 && deltaY < 5) {
        this.isChatVisible = !this.isChatVisible
      }

      this.dragging = false
    },
    /** 获取聊天窗口列表 **/
    async fetchChatList() {
      getAction('/ai/list').then((res) => {
        this.chatList = res.data
      })
    },
    /** 选择聊天窗口 **/
    selectChat(chat) {
      this.currentChatId = chat.chatId
      this.currentChatName = chat.chatName

      getAction('/ai/one', { chatId: chat.chatId }).then((res) => {
        this.chatMessages = res.data.chatContent ? JSON.parse(res.data.chatContent) : []
        this.scrollToBottom()
      })
    },
    /** 创建新聊天 **/
    createNewChat() {
      postAction('/ai/newChat').then((res) => {
        if (res.code == 200) {
          this.fetchChatList()
          this.currentChatId = res.data.chatId
          this.currentChatName = res.data.chatName
          this.chatMessages = []
        } else {
          this.$message.error(res.msg)
        }
      })
    },

    /** 发送消息 **/
    sendMessage() {
      if (this.isAnswering[this.currentChatId]) return
      this.isAnswering[this.currentChatId] = true
      if (!this.userInput.trim() || !this.currentChatId) return
      const newMessage = {
        messageType: 'USER',
        textContent: this.userInput,
      }
      var chatid = this.currentChatId
      this.chatMessages.push(newMessage)
      if (this.chatMessages.length == 1) {
        console.log('第一次聊天')
        var a = this.chatList.findIndex((item) => {
          if (item.chatId == chatid) return item
        })
        this.chatList[a].chatName = this.userInput.length > 7 ? this.userInput.substring(0, 7) + '...' : this.userInput
        this.currentChatName = this.chatList[a].chatName
      }

      this.$nextTick(() => {
        this.scrollToBottom()
      })

      // 关闭之前的连接，避免重复请求
      if (this.eventSource[chatid]) {
        this.eventSource[chatid].close()
      }

      // 开始流式请求
      this.eventSource[chatid] = new EventSource(
        `/api/ai/stream?chatId=${chatid}&message=${encodeURIComponent(this.userInput)}&token=${Vue.ls.get(
          ACCESS_TOKEN
        )}`
      )

            // 错误处理
      this.eventSource[chatid].onerror = () => {
        this.$message.error('未知错误')
        this.eventSource[chatid].close()
        this.flexChat[chatid] = undefined
        this.isAnswering[chatid] = false
      }

      // 接收消息
      this.eventSource[chatid].onmessage = (event) => {
        try {
          const data = JSON.parse(event.data)
          if (data.textContent == '123END123') {//结束标志
            this.chatMessages.push({
              textContent: this.flexChat[data.chatId],
              messageType: 'Assistant',
            })
            this.$delete(this.flexChat, data.chatId) // 使用响应式删除
            this.isAnswering[data.chatId] = false
            // 增加关闭操作
            if (this.eventSource[data.chatId]) {
              this.eventSource[data.chatId].close()
              delete this.eventSource[data.chatId]
            }
          } else {
            this.$set(this.flexChat, data.chatId, (this.flexChat[data.chatId] || '') + data.textContent)
          }
          if (data.chatId == chatid) {
            this.$nextTick(() => {
              this.scrollToBottom()
            })
          }
        } catch (e) {
          console.error('消息解析错误：', e)
        }
      }



      this.userInput = ''
    },
    confirmDeleteChat(chatId) {
      this.$confirm({
        title: '确认删除',
        content: '删除后将无法恢复，是否继续？',
        okText: '确认',
        cancelText: '取消',
        onOk: () => this.deleteChat(chatId),
      })
    },
    deleteChat(chatId) {
      deleteAction('/ai', { chatId: chatId }).then((res) => {
        if (res.code == 200) {
          this.$message.success('聊天已删除')
          // 如果当前聊天窗口被删除，清空聊天内容
          if (this.currentChatId === chatId) {
            this.currentChatId = null
            this.currentChatName = ''
            this.chatMessages = []
          }
          this.fetchChatList()
        }
      })
      this.chatList = this.chatList.filter((chat) => chat.chatId !== chatId)
    },
    scrollToBottom() {
      this.$nextTick(() => {
        const chatContent = this.$refs.chatContent
        if (chatContent) {
          //   chatContent.scrollTop = chatContent.scrollHeight
          chatContent.scrollTo({
            top: chatContent.scrollHeight,
            behavior: 'smooth',
          })
        }
      })
    },
  },
}
</script>

<style scoped>
.selected-chat {
  background-color: #e6f7ff;
}
.chat-float-button {
  position: fixed;
  width: 50px;
  height: 50px;
  background-color: #1890ff;
  color: white;
  font-size: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  cursor: grab;
  z-index: 1000;
}

.chat-box {
  position: fixed;
  right: 20px;
  bottom: 20px;
  width: 480px;
  height: 650px;
  background: white;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  z-index: 1000;
}

.chat-header {
  background: #1890ff;
  color: white;
  padding: 10px;
  font-size: 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.chat-body {
  display: flex;
  flex: 1;
  overflow: hidden;
}

.chat-list {
  width: 180px;
  border-right: 1px solid #ddd;
  padding: 10px;
}

.chat-list-items {
  max-height: 500px;
  overflow-y: auto;
}

.chat-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.chat-name {
  flex: 1;
  cursor: pointer;
}

.chat-name:hover {
  color: #1890ff;
}

.chat-content {
  flex: 1;
  padding: 10px;
  overflow-y: auto;
}

.chat-message {
  max-width: 75%;
  margin: 5px 0;
  padding: 8px;
  border-radius: 6px;
  word-wrap: break-word;
}

.chat-message-user {
  background: #3ed1fe;
  color: white;
  align-self: flex-end;
}

.chat-message-ai {
  background: #f0f0f0;
  color: black;
  align-self: flex-start;
}

.chat-footer {
  display: flex;
  padding: 10px;
  border-top: 1px solid #ddd;
}

.chat-footer input {
  flex: 1;
  margin-right: 5px;
}

/* 右侧滑出动画 */
.slide-enter-active,
.slide-leave-active {
  transition: transform 0.3s ease-out;
}
.slide-enter {
  transform: translateX(100%);
}
.slide-leave-to {
  transform: translateX(100%);
}
</style>
